<?
    $help['sandbox:run'] = 'building sandbox';
    $opt['sandbox:run'] = array();
    
    function cmd_sandbox_run($clean = false){
        if(!is_branch_dir()){
            error('Build process should run in branch directory');
        }
        global $build, $vars;
        read_props($vars);
        $lv = $vars;
        
        $mode = $vars['misc.builder.mode'] ? $vars['misc.builder.mode'] : 'PRODUCTION';
        
        foreach($build as $path => $cmp){
            if(preg_match('/^\?/', $path)){
                $path = substr($path, 1);
                if(!file_exists($path)){
                    echo "Skip [$path]\n";
                    continue;
                }
            }
            echo "\n" . ($clean ? 'Cleaning' : 'Building') . " [$path]\n";
            $p = array_key_exists('build-prop', $cmp) ? $cmp['build-prop'] : array();
            if(($len = count($p))){
                for($i = 0; $i < $len; $i++)
                    load_props($path . '/' . proc_prop($p[$i], $lv), $lv);
                proc_prop(null, $lv);
            }
            if(array_key_exists('make', $cmp)){
                if(!array_key_exists($mode, $cmp['make']))
                    error('declared build mode [' . $mode . '] is not exists in build.yaml');

                foreach($cmp['make'][$mode] as $cmd => $val){
                    switch($cmd){
                        case 'copy':
                            echo "\t" . ($clean ? "removing" : "processing") . " files:\n";
                            $len = count($val);
                            for($i = 0; $i < $len; $i++){
                                list($src, $dst) = explode('=', proc_prop($val[$i], $lv), 2);
                                if(!$dst){
                                    $dst = $src;
                                    $src = $src . '-dist';
                                }
                                $src = makePath($path, $src);
                                if(!file_exists($src)){
                                    echo "$src not exists, skip...";
                                    continue;
                                }
                                $dst = makePath($path, $dst);
                                if(!$clean){
                                    echo "\t\t$src -> $dst\n";
                                    proc_prop_tpl($src, $dst, $lv, false, true);
                                } else {
                                    echo "\t\t$dst\n";
                                    @unlink(makePath($path, $dst));
                                }
                            }
                            break;
                        case 'ext-copy':
                            echo "\t" . ($clean ? "removing" : "processing") . " external files:\n";
                            $len = count($val);
                            for($i = 0; $i < $len; $i++){
                                list($src, $dst) = explode('=', proc_prop($val[$i], $lv), 2);
                                if(!$dst){
                                    $dst = $src;
                                    $src = $src . '-dist';
                                }
                                $dst = makePath($path, $dst);
                                if(!$clean){
                                    echo "\t\t$src -> $dst\n";
                                    proc_prop_tpl($src, $dst, $lv, false, true);
                                } else {
                                    echo "\t\t$dst\n";
                                    @unlink(makePath($path, $dst));
                                }
                            }
                            break;
                        case 'link':
                            echo "\t" . ($clean ? "removing" : "creating") . " links:\n";
                            for($i = count($val); --$i >= 0;){
                                list($target, $link) = explode('=', proc_prop($val[$i], $lv), 2);
                                $tf = pathinfo($target);
                                $lf = pathinfo($link);
                                $target = makePath(getRelativePath($tf['dirname'], $lf['dirname']), $tf['basename']);
                                $link = makePath(getRelativePath($lf['dirname'], $lv['base.dir']), $lf['basename']);
                                echo "\t\t$target -> $link\n";
                                if(!$clean)
                                    @symlink($target, $link);
                                else
                                    @unlink($link);
                            }
                            break;
                        case 'mkdir':
                            echo "\t" . ($clean ? "removing" : "creating") . " directories:\n";
                            for($i = count($val); --$i >= 0;){
                                echo "\t\t" . ($d = makePath($path, proc_prop($val[$i], $lv))) . "\n";
                                if(!$clean){
                                    exec("mkdir -p $d && chmod 0777 $d && sudo chown 33 $d");
                                } else
                                    exec('sudo rm -fr ' . $d);
                            }
                            break;
                        case 'patch':
                            if($clean) continue;
                            echo "\tpatching files:\n";
                            foreach($val as $f => $p){
                                echo "\t\t" . ($d = makePath($path, proc_prop($f, $lv))) . "\n";
                                $file = file_get_contents($d);
                                foreach($p as $l => $r)
                                    $file = preg_replace($l, $r, $file);
                                file_put_contents($d, $file);
                            }
                            break;
                        case 'prepend':
                            if($clean) continue;
                            echo "\tprepending files:\n";
                            foreach($val as $f => $p){
                                echo "\t\t" . ($d = makePath($path, proc_prop($f, $lv))) . "\n";
                                $file = file_get_contents($d);
                                $file = proc_prop($p, $lv) . $file;
                                file_put_contents($d, $file);
                            }
                            break;
                        case 'run':
                            if($clean) continue;
                            echo "\trun scripts:\n";
                            foreach($val as $c => $p){
                                echo "=\n" . ($cmd = preg_replace('!' . preg_quote($lv['base.dir'], '!') . '!', '.', (proc_prop($c, $lv) . ' ' . proc_prop($p, $lv)))) . "\n----\n";
                                system($cmd, $ret);
                                if($ret != 0)
                                    error('external command return non-zero exit code');
                            }
                            break;
                    }
                }
            }
        }
        if(!$clean && $vars['misc.map.user']){
            echo "mapping user...\n";
            passthru("sudo chown {$vars['misc.map.user']} -R ./");
        }
        if(!$clean && $vars['misc.map.chmod']){
            echo "chmod'ing files...\n";
            passthru("sudo chmod {$vars['misc.map.chmod']} -R ./");
        }
    }
    